#include <linux/module.h>
#include <linux/workqueue.h>
#include <linux/delay.h>


// 变量定义
static struct workqueue_struct *my_wq;
static struct work_struct my_work;
static struct delayed_work my_delay_work;

// 普通工作处理函数
static void my_work_func(struct work_struct *work) {
    pr_info("Normal work: Executing on cpu %d\n", smp_processor_id());
    pr_info("Normal work: can sleep if needed\n");
    msleep_interruptible(1000);
} 

// 延时工作处理函数
static void my_delayed_work_func(struct work_struct *work) {
    struct delayed_work *dwork = to_delayed_work(work);
    pr_info("Delayed work: Excute delayed on cpu %d\n", smp_processor_id());
}

// 模块初始化函数
static int __init basicwork_init(void) {
    pr_info("basic_test example init\n");

    // 创建自己的专用工作队列
    my_wq = create_singlethread_workqueue("my_example_queue");
    if (!my_wq) {
        pr_err("failed to create my workqueue\n");
        return -ENOMEM;
    }

    // 工作动态初始化
    INIT_WORK(&my_work, my_work_func);
    INIT_DELAYED_WORK(&my_delay_work, my_delayed_work_func);

    // 在专用工作队列中调度工作
    pr_info("scheduling normal work\n");
    queue_work(my_wq, &my_work);

    pr_info("scheduling delayed work\n");
    queue_delayed_work(my_wq, &my_delay_work, msecs_to_jiffies(200));
    
    return 0;
}

// 模块退出函数
static void __exit basicwork_exit(void) {
    pr_info("basic_test example exit\n");

    // 检查普通工作是否已调度
    if (work_pending(&my_work)) {
        pr_info("Cancel pending work\n");
        cancel_work_sync(&my_work);
    }

    // 检查延迟工作是否已经被调度
    if (delayed_work_pending(&my_delay_work)) {
        pr_info("cancel pending delayed work\n");
        cancel_delayed_work_sync(&my_delay_work);
    }

    // 取消工作队列上的所有工作
    flush_workqueue(my_wq);
    // 销毁工作队列
    if (my_wq) {
        destroy_workqueue(my_wq);
        my_wq = NULL;
    }
    pr_info("Clean up\n");
}

module_init(basicwork_init);
module_exit(basicwork_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("LUO");
MODULE_VERSION("1.0");
MODULE_DESCRIPTION("A basic, simple example of workqueue");